#pragma once
#ifndef __RESPONSE_H__
#define __RESPONSE_H__

#include <msg/message.h>
#include <msg/request.h>

enum class response_code: uint32_t{
    SUCCESS,
    FAILED,
    UNKNOWN_OP
};

struct alignas(32) response_head{
    request_op op;
    uint32_t req_id;
    response_code code;

    void transform_to_network_byte_order(){
        htonl(static_cast<uint32_t>(code));
    }

    void transform_to_host_byte_order(){
        ntohl(static_cast<uint32_t>(code));
    }

    response_head& operator=(const response_head& h){
        code = h.code;
        return *this;
    }
};



struct response : message{
    response(){
        set_message_type(MessageType::RESPONSE);
    }

    response(message msg){
        *static_cast<message*>(this) = msg;
    }

    response_head get_head(){
        response_head head = *get_head_ptr();
        head.transform_to_host_byte_order();
        return head;
    }

    void set_head(response_head head){
        head.transform_to_network_byte_order();
        set_content(0, &head, sizeof(head));
        // *get_head_ptr() = head;
    }

    std::any get_body(){
        // 拿出的时候转换下字节序
        switch (get_head().op)
        {
            using enum request_op;
        case LOG_IN:
            return {};
        
        case CREATE_FORWARD_RULE:
            return {};

        case CRAETE_OUTPUT_FORWARD_RULE:
            return {};
        
        case CREATE_VIRTUAL_CLIENT:{
            // Endpoint addr = *reinterpret_cast<Endpoint*>(get_body_ptr());
            uint32_t app_id = *reinterpret_cast<uint32_t*>(get_body_ptr());
            app_id = ntohl(app_id);
            // rule_net_order.transform_to_host_byte_order();
            return app_id;
        }
        }
    }

    void set_body(void* ptr, uint32_t size){
        set_content(RESPONSE_HEAD_SIZE, ptr, size);
    }

    size_t get_body_size(){
        return get_router_info().data_size - RESPONSE_HEAD_SIZE;
    }

protected:
    response_head* get_head_ptr(){
        return reinterpret_cast<response_head*>(get_content_ptr(0));
    }

    void* get_body_ptr(){
        return get_content_ptr(RESPONSE_HEAD_SIZE);
    }
public:
    static const size_t RESPONSE_HEAD_SIZE = sizeof(response_head);
};

#endif // __RESPONSE_H__